<!doctype html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件管理系统</title>
    <!-- 引入图标库 -->
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <style>
        /* 全局样式重置与基础配置 */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Inter', 'Microsoft YaHei', Arial, sans-serif;
        }

        body {
            margin: 0;
            padding: 2rem 1rem;
            line-height: 1.5;
            font-family: 'Inter', 'Microsoft YaHei', Arial, sans-serif;
            color: #334155;
            overflow-x: hidden;
            position: relative;
            min-height: 100vh;
            background: linear-gradient(135deg, #e0f2fe 0%, #eef2ff 50%, #f8fafc 100%);
        }

        /* 背景旋转渐变层 */
        /* 绿蓝清新风格旋转背景 */
        body::before {
            content: "";
            position: fixed;
            top: -50%;
            left: -50%;
            width: 200%;
            height: 200%;
            background: conic-gradient(
                    #ecfdf5,   /* 极浅绿色背景，清新打底 */
                    #6ee7b7,   /* 薄荷绿 */
                    #3b82f6,   /* 天空蓝 */
                    #22d3ee,   /* 湖水蓝 */
                    #10b981,   /* 草木绿 */
                    #ecfdf5    /* 回到浅绿，柔和衔接 */
            );
            animation: rotateBG 25s linear infinite;
            z-index: -2;
            opacity: 0.65; /* 半透明，保证内容清晰 */
        }

        @keyframes rotateBG {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }


        /* 装饰模糊光斑 */
        body::after {
            content: '';
            position: absolute;
            width: 500px;
            height: 500px;
            border-radius: 50%;
            filter: blur(160px);
            background: radial-gradient(circle, rgba(16,185,129,0.25), transparent);
            bottom: -150px;
            right: -120px;
            z-index: -1;
        }

        /* 容器：居中+限制宽度 */
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 0 1rem;
            position: relative;
            z-index: 1;
        }

        /* 标题样式 */
        h1 {
            position: relative;
            display: inline-block;
            font-size: 2rem;
            font-weight: 600;
            margin-bottom: 3rem;
            border-left: 4px solid #3b82f6;
            padding-left: 1rem;
            background: linear-gradient(90deg, #3b82f6, #6366f1);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
        }

        /* 标题下动态渐变条 */
        h1::after {
            content: "";
            position: absolute;
            left: 0;
            bottom: -10px;
            width: 100%;
            height: 4px;
            border-radius: 2px;
            background: linear-gradient(90deg, #3b82f6, #6366f1, #10b981, #3b82f6);
            background-size: 300% 100%;
            animation: gradient-move 6s linear infinite;
        }

        @keyframes gradient-move {
            0% { background-position: 0% 50%; }
            100% { background-position: 100% 50%; }
        }

        /* 二级标题 */
        h2 {
            color: #1e293b;
            font-size: 1.3rem;
            margin-bottom: 1.5rem;
            font-weight: 500;
            display: flex;
            align-items: center;
        }

        h2::before {
            content: "";
            display: inline-block;
            width: 8px;
            height: 20px;
            background: linear-gradient(180deg, #3b82f6, #6366f1);
            margin-right: 0.8rem;
            border-radius: 2px;
        }

        /* 卡片组件 */
        .card {
            background: linear-gradient(145deg, #ffffff, #f9fafb);
            border-radius: 14px;
            box-shadow: 0 6px 20px rgba(0,0,0,0.08);
            padding: 2rem;
            margin-bottom: 2rem;
            border-top: 4px solid transparent;
            position: relative;
            overflow: hidden;
            transition: all 0.3s ease;
        }

        .card::before {
            content: '';
            position: absolute;
            top: 0;
            left: -50%;
            width: 200%;
            height: 100%;
            background: linear-gradient(120deg, rgba(255,255,255,0.4) 0%, transparent 60%);
            transform: skewX(-15deg);
            pointer-events: none;
        }

        .card:hover {
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
            transform: translateY(-2px);
        }

        .upload-section {
            border-top-color: #3b82f6;
        }

        .file-list {
            border-top-color: #10b981;
        }

        /* 表单 */
        .form-group {
            margin-bottom: 1.2rem;
        }

        label {
            display: block;
            margin-bottom: 0.5rem;
            color: #475569;
            font-size: 0.95rem;
        }

        input[type="text"],
        input[type="password"],
        input[type="file"] {
            width: 100%;
            padding: 0.8rem 1rem;
            border: 1px solid #e2e8f0;
            border-radius: 6px;
            font-size: 0.95rem;
            transition: all 0.3s ease;
        }

        input[type="text"]:focus,
        input[type="password"]:focus {
            outline: none;
            border-color: #3b82f6;
            box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
        }

        input[type="file"] {
            border: 1px dashed #e2e8f0;
            background-color: #f8fafc;
            cursor: pointer;
        }

        input[type="file"]:hover {
            border-color: #3b82f6;
            background-color: #f0f5ff;
        }

        /* 按钮 */
        .btn {
            padding: 0.7rem 1.2rem;
            border: none;
            border-radius: 6px;
            font-size: 0.9rem;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.3s ease;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 0.3rem;
        }

        .btn-primary {
            background-image: linear-gradient(180deg, #4f46e5, #3b82f6);
            color: #ffffff;
        }

        .btn-view {
            background-image: linear-gradient(180deg, #16a372, #10b981);
            color: #ffffff;
        }

        .btn-delete {
            background-image: linear-gradient(180deg, #dc2626, #ef4444);
            color: #ffffff;
        }

        .btn:hover {
            transform: scale(1.05);
            box-shadow: 0 0 12px rgba(0,0,0,0.15), 0 0 16px currentColor;
        }

        .btn:active {
            transform: scale(0.97);
            box-shadow: none;
        }

        /* 文件列表 */
        .file-item {
            display: flex;
            align-items: center;
            padding: 1rem 1.2rem;
            border-bottom: 1px solid #f1f5f9;
            transition: all 0.3s ease;
        }

        .file-item:last-child {
            border-bottom: none;
        }

        .file-item:hover {
            background: linear-gradient(90deg, #f0f9ff, #ecfdf5);
            transform: translateX(3px);
            border-radius: 6px;
        }

        .file-name {
            font-size: 0.95rem;
            color: #334155;
            flex: 1;
            display: flex;
            align-items: center;
        }

        .file-meta {
            font-size: 0.85em;
            color: #666;
        }
        
        .file-meta i {
            margin-right: 4px;
            color: #888;
        }

        .file-actions {
            margin-left: auto;
            display: flex;
            gap: 0.5rem;
        }
        
        .error-text {
            color: #dc3545;
            text-align: center;
            padding: 20px;
        }
        
        .btn-retry {
            margin-top: 10px;
            background-color: #6c757d;
            color: white;
            border: none;
            padding: 8px 16px;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.2s;
        }
        
        .btn-retry:hover {
            background-color: #5a6268;
        }
        
        .btn-retry i {
            margin-right: 6px;
        }

        /* 状态提示 */
        .status-text {
            text-align: center;
            padding: 3rem 1rem;
            color: #64748b;
            font-size: 1rem;
            background: linear-gradient(135deg, #f8fafc, #f1f5f9);
            border: 1px dashed #cbd5e1;
            border-radius: 6px;
            margin-top: 1rem;
        }

        .status-text::before {
            content: "";
            display: inline-block;
            width: 40px;
            height: 40px;
            margin-bottom: 1rem;
            border: 3px solid #e2e8f0;
            border-top-color: #3b82f6;
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }

        .empty-text::before {
            animation: none;
            border: none;
            background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z'/%3E%3Cpolyline points='3.29 7 12 12 20.71 7'/%3E%3Cline x1='12' y1='22' x2='12' y2='12'/%3E%3C/svg%3E") no-repeat center;
        }
        .crtl{
            padding: 0.7rem 1.2rem;
            border: none;
            border-radius: 6px;
            font-size: 0.9rem;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.3s ease;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 0.3rem;
        }
        /* 基础链接样式 - 与主题色调呼应 */
        a {
            color: #4299e1;
            text-decoration: none;
            font-weight: 500;
            position: relative;
            padding: 0 2px;
            transition: all 0.3s ease;
            border-radius: 3px;
            font-size: 20px;
        }

        /* 链接下划线动画效果 */
        a::after {
            content: '';
            position: absolute;
            bottom: -2px;
            left: 0;
            width: 0;
            height: 2px;
            background: linear-gradient(90deg, #4299e1 0%, #8b5cf6 100%);
            transition: width 0.3s ease;
            border-radius: 2px;
        }

        /* 悬停状态 - 增强交互反馈 */
        a:hover {
            color: #3182ce;
            background-color: rgba(66, 153, 225, 0.05);
        }

        a:hover::after {
            width: 100%;
        }

        /* 激活状态 - 点击反馈 */
        a:active {
            color: #2b6cb0;
            background-color: rgba(66, 153, 225, 0.1);
        }

        /* 已访问链接 - 保持和谐但有区分 */
        a:visited {
            color: #6b7280;
        }

        /* 带图标链接的特殊样式（如需配合Font Awesome使用） */
        a.with-icon {
            display: inline-flex;
            align-items: center;
            gap: 6px;
        }

        a.with-icon i {
            transition: transform 0.3s ease;
        }

        a.with-icon:hover i {
            transform: translateX(3px);
        }

    </style>
</head>
<body>
<div class="container">
    <h1>文件管理系统</h1>
<div class="crtl">
    <a href="dashboard.html" style="accent-color:coral">返回控制台</a>
</div>
    <!-- 上传文件卡片 -->
    <div class="card upload-section">
        <h2>上传文件</h2>
        <form id="uploadForm" action="/login-itheimaservlet/mynote/Upload" method="post" enctype="multipart/form-data">
            <div class="form-group">
                <label for="username">用户                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    名</label>
                <input type="text" id="username" name="username" value="" required>
            </div>
            <div class="form-group">
                <label for="file">选择文件</label>
                <input type="file" id="file" name="file" required>
            </div>
            <button type="submit" class="btn btn-primary" id="uploadBtn">
                <i class="fa fa-upload mr-2"></i>
                上传文件
            </button>
            <div id="progressWrap" style="display:none;margin-top:10px">
                <div style="height:10px;background:#e5e7eb;border-radius:6px;overflow:hidden">
                    <div id="progressBar" style="height:10px;width:0%;background:#2563eb;transition:width .2s"></div>
                </div>
                <div id="progressText" style="font-size:12px;color:#64748b;margin-top:6px">0%</div>
            </div>
        </form>
    </div>

    <!-- 文件列表卡片 -->
    <div class="card file-list">
        <h2>已上传文件</h2>
        <div class="file-list-container" id="fileList">
            <div class="status-text">加载中...</div>
        </div>
    </div>
</div>

<script>
    const PROJECT_NAME = '/login-itheimaservlet';

    function formatDate(dateString) {
        if (!dateString) return "未知时间";
        try {
            const date = new Date(dateString);
            if (isNaN(date.getTime())) {
                throw new Error('无效日期');
            }
            return date.toLocaleString('zh-CN', {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit'
            });
        } catch (error) {
            console.error('日期格式化错误:', error);
            return "日期格式错误";
        }
    }

    async function viewFile(filename) {
        try {
            const response = await fetch(`${PROJECT_NAME}/mynote/View?filename=${encodeURIComponent(filename)}`);
            
            if (!response.ok) {
                const contentType = response.headers.get('content-type');
                const errorData = contentType?.includes('application/json') 
                    ? await response.json()
                    : { error: '查看文件失败', detail: await response.text() };
                throw new Error(errorData.detail || errorData.error || '查看文件失败');
            }
            
            window.open(`${PROJECT_NAME}/mynote/View?filename=${encodeURIComponent(filename)}`, '_blank');
        } catch (error) {
            console.error('查看文件错误:', error);
            alert(`查看文件失败: ${error.message}`);
        }
    }

    async function deleteFile(filename) {
        if (!confirm(`确定要删除文件「${filename}」吗？删除后无法恢复`)) {
            return;
        }
        
        try {
            const response = await fetch(
                `${PROJECT_NAME}/mynote/Delete?filename=${encodeURIComponent(filename)}`, 
                { method: 'POST' }
            );
            
            if (!response.ok) {
                const contentType = response.headers.get('content-type');
                const errorData = contentType?.includes('application/json')
                    ? await response.json()
                    : { error: '删除失败', detail: await response.text() };
                throw new Error(errorData.detail || errorData.error || '删除失败');
            }
            
            alert('删除成功');
            await loadFileList();
        } catch (error) {
            console.error('删除错误:', error);
            alert(`删除失败: ${error.message}`);
        }
    }

    async function loadFileList() {
        const fileListDiv = document.getElementById("fileList");
        fileListDiv.innerHTML = '<div class="status-text">加载中...</div>';

        try {
            const response = await axios.post(`${PROJECT_NAME}/mynote/List`);
            
            if (!response.data) {
                throw new Error('服务器返回空数据');
            }
            
            // 检查是否是错误响应
            if (response.data.error) {
                throw new Error(response.data.detail || response.data.error);
            }
            
            const files = Array.isArray(response.data) ? response.data : [];
            
            if (files.length === 0) {
                fileListDiv.innerHTML = '<div class="status-text empty-text">暂无上传文件，点击上方"上传文件"添加</div>';
                return;
            }

            fileListDiv.innerHTML = '';
            
            files.forEach(file => {
                if (!file || !file.filename) {
                    console.warn('跳过无效的文件数据:', file);
                    return;
                }

                const filename = file.filename;
                const filesize = file.filesize 
                    ? (file.filesize / 1024).toFixed(2) + " KB" 
                    : "未知大小";
                const uploadTime = formatDate(file.uploadTime);
                const username = file.username || '未知用户';

                const item = document.createElement("div");
                item.className = "file-item";
                item.innerHTML = `
                    <div class="file-info">
                        <span class="file-name">${filename}</span>
                        <span class="file-meta">
                            <i class="fa fa-file-o"></i> ${filesize} 
                            | <i class="fa fa-clock-o"></i> ${uploadTime}
                            | <i class="fa fa-user"></i> ${username}
                        </span>
                    </div>
                    <div class="file-actions">
                        <button class="btn btn-view" onclick="viewFile('${filename}')">
                            <i class="fa fa-eye"></i> 查看
                        </button>
                        <button class="btn btn-delete" onclick="deleteFile('${filename}')">
                            <i class="fa fa-trash"></i> 删除
                        </button>
                    </div>
                `;
                fileListDiv.appendChild(item);
            });
        } catch (error) {
            console.error('加载列表错误:', error);
            const errorMessage = error.response?.data?.detail || error.response?.data?.error || error.message;
            fileListDiv.innerHTML = `
                <div class="status-text error-text">
                    加载失败: ${errorMessage}<br>
                    <button onclick="loadFileList()" class="btn btn-retry">
                        <i class="fa fa-refresh"></i> 重试
                    </button>
                </div>
            `;
        }
    }

    window.onload = loadFileList;

    // 动态显示文件名与上传进度（AJAX上传）
    (function(){
        const fileInput = document.getElementById('file');
        const uploadBtn = document.getElementById('uploadBtn');
        const form = document.getElementById('uploadForm');
        const progressWrap = document.getElementById('progressWrap');
        const progressBar = document.getElementById('progressBar');
        const progressText = document.getElementById('progressText');

        fileInput.addEventListener('change', function(){
            const f = this.files && this.files[0];
            if (f) {
                uploadBtn.innerHTML = '<i class="fa fa-upload mr-2"></i> 上传 ' + f.name;
            } else {
                uploadBtn.innerHTML = '<i class="fa fa-upload mr-2"></i> 上传文件';
            }
        });

        form.addEventListener('submit', function(e){
            e.preventDefault();
            const f = fileInput.files && fileInput.files[0];
            if (!f) {
                alert('请先选择文件');
                return;
            }
            const formData = new FormData(form);
            const xhr = new XMLHttpRequest();
            xhr.open('POST', PROJECT_NAME + '/mynote/Upload');
            progressWrap.style.display = 'block';
            progressBar.style.width = '0%';
            progressText.textContent = '0%';

            xhr.upload.onprogress = function(e){
                if (e.lengthComputable) {
                    const percent = Math.round((e.loaded / e.total) * 100);
                    progressBar.style.width = percent + '%';
                    progressText.textContent = percent + '%';
                }
            };

            xhr.onreadystatechange = function(){
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        progressText.textContent = '上传完成';
                        alert('上传成功');
                        loadFileList();
                        // 重置表单与按钮文字
                        form.reset();
                        uploadBtn.innerHTML = '<i class="fa fa-upload mr-2"></i> 上传文件';
                        setTimeout(()=>{ progressWrap.style.display='none'; }, 600);
                    } else {
                        const msg = xhr.responseText || '上传失败';
                        alert('上传失败: ' + msg);
                    }
                }
            };

            xhr.onerror = function(){
                alert('网络错误，上传失败');
            };

            xhr.send(formData);
        });
    })();
</script>
</body>
</html>
